import { BufferGeometry, Line, LineDashedMaterial, Mesh, MeshBasicMaterial, Raycaster, Sphere, SphereGeometry, Vector3 } from "../libs/three146/three.module.js";
import { Ball } from "./Ball.js";
import * as CANNON from '../libs/cannon-es.js'

class WhiteBall extends Ball{ 
    constructor(game, x,z){ 
        super(game,x,z);
        this.forward = new Vector3()
        this.guideLine = this.createGuideLine()
        game.scene.add(this.guideLine);

        this.dot = this.createIntersectionDot();
        game.scene.add(this.dot)
        this.preview = false ;
        window.addEventListener('keydown', (e)=> { 
            if(e.key !== 'h'){ return } 
            this.preview = !this.preview
        })
        this.raycaster  =new Raycaster()

    }

    createGuideLine(){ 
        const points = [] ;
        points.push( new Vector3(), new Vector3(0,0,-1)) ;
        const geo = new BufferGeometry().setFromPoints(points) ;
        const mat  = new LineDashedMaterial({ color: 0xffffff,dashSize: .05, gapSize:.03}) ;

        const line = new Line(geo,mat ) ;
        line.getWorldScale.z = 3 ;
        line.visible =false ;
        // this.game.scene.add(line) ;
        line.computeLineDistances() // 会计算每个点到起点的距离

        return line 
    }
    //就是建立一个球mesh
    createIntersectionDot(){ 
        return  new Mesh(new SphereGeometry(.01, 4,4), new MeshBasicMaterial({ transparent:true , color:0xffff, opacity: .5}))

    }
    //进洞丢一命 复活 

    onEnterHole(){ 
        this.reset()
        console.log('重生');
    }

    update(dt){ 
        super.update(dt) ;
        if(this.body.position.y < -Ball.RADIUS){ 
            this.onEnterHole()
        }
        this.isSleeping = this.body.sleepState === CANNON.Body.SLEEPING ;
        if( this.isSleeping){ 
            this.updateGuideLine()
        }else { 
            this.guideLine.visible =false ;
            this.dot.visible =false ;
        }
    }
// 指示线更新
    updateGuideLine(){ 
        if(!this.balls) {
            this.balls = this.game.balls.map(b=> b.mesh) ;
            this.balls.shift()
    }
        const angle = this.game.controls.getAzimuthalAngle() ;

        this.guideLine.position.copy(this.mesh.position) ;
        this.guideLine.rotation.y= angle ;

        this.guideLine.visible =true ;
        // forward 初始值是 （0，0， -1） 下面这个操作就没把初始值当回事 小球本来就没有父级，所以position本身就是世界位 ,guideline 也是 所以下面没必要
        // this.guideLine.getWorldPosition(this.forward) ; 我就说嘛，搞错方法了
        this.guideLine.getWorldDirection(this.forward)
        // this.forward.set()
        this.forward.negate() // 取反 是因为默认方向是z轴，我们摆放的前面正好就是 -z轴

        this.raycaster.set(this.mesh.position, this.forward) // 预判球的撞击点

        let insects = this.raycaster.intersectObjects(this.balls) ;
        // 先检测会不会撞球，如果不，就检测撞墙
        if(insects.length){ 
            this.guideLine.scale.z = insects[0].distance ; // 这个距离属性真方便啊
            this.dot.position.copy(insects[0].point) ;
            this.dot.visible =true ;
        }else { 
            insects =this.raycaster.intersectObjects(this.game?.edges?.children ||[]) ;
            if(insects.length) { 
                this.guideLine.scale.z = insects[0].distance ; // 这个距离属性真方便啊
                // 这里可以搞一个弹射追踪 递归。不递归了，至多弹射三次吧
            }
            this.dot.visible =false;
        }
    }
}

export {WhiteBall}